package com.aichat.ai_chatbackend.service.impl;

import com.aichat.ai_chatbackend.model.dto.chat.ChatRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;

@Service
@Slf4j
public class CompanionChatService {

    @Value("${ai.service.url:http://localhost:8001}")
    private String aiServiceUrl;

    /**
     * 修复UTF-8编码问题的流式聊天方法
     */
    public void chatWithCompanionStream(String userId, ChatRequest request, SseEmitter emitter) {
        CompletableFuture.runAsync(() -> {
            try {
                log.info("调用AI流式服务 - 用户: {}, 消息: {}", userId, request.getUserMessage());

                // 检查AI服务是否可用
                if (!isAiServiceHealthy()) {
                    log.warn("AI服务不可用，使用fallback模式");
                    createFallbackStreamResponse(userId, request, emitter);
                    emitter.complete();
                    return;
                }

                try {
                    // 调用Python流式服务
                    callPythonStreamingServiceWithEncodingFix(userId, request, emitter);

                } catch (Exception aiServiceException) {
                    log.warn("外部AI流式服务异常，使用fallback模式: {}", aiServiceException.getMessage());
                    createFallbackStreamResponse(userId, request, emitter);
                    emitter.complete();
                }

            } catch (Exception e) {
                log.error("流式对话处理异常: {}", e.getMessage(), e);
                try {
                    emitter.send(SseEmitter.event()
                            .name("error")
                            .data("服务器内部错误: " + e.getMessage()));
                } catch (Exception sendException) {
                    log.error("发送错误信息失败: {}", sendException.getMessage());
                }
                emitter.completeWithError(e);
            }
        });
    }

    /**
     * 创建支持UTF-8编码的WebClient
     */
    private WebClient createWebClientWithEncodingSupport() {
        return WebClient.builder()
                .baseUrl(aiServiceUrl)
                .defaultHeader("Accept", "text/event-stream")
                .defaultHeader("Accept-Charset", "utf-8")
                .defaultHeader("Cache-Control", "no-cache")
                .codecs(configurer -> {
                    configurer.defaultCodecs().maxInMemorySize(10 * 1024 * 1024);
                    // 设置默认字符编码
                    configurer.defaultCodecs().enableLoggingRequestDetails(true);
                })
                .build();
    }

    /**
     * 修复编码问题的Python流式服务调用
     */
    private void callPythonStreamingServiceWithEncodingFix(String userId, ChatRequest request, SseEmitter emitter) {
        try {
            WebClient webClient = createWebClientWithEncodingSupport();
            log.info("开始调用Python流式服务: {}/chat/stream", aiServiceUrl);

            // 方案1: 直接获取字符串流，避免SSE解析问题
            Flux<String> stringStream = webClient.get()
                    .uri(uriBuilder -> uriBuilder
                            .path("/chat/stream")
                            .queryParam("sessionId", request.getSessionId())
                            .queryParam("userCurrentMessage", request.getUserMessage())
                            .build())
                    .accept(MediaType.TEXT_EVENT_STREAM)
                    .acceptCharset(StandardCharsets.UTF_8)
                    .retrieve()
                    .bodyToFlux(String.class);

            // 处理字符串流
            stringStream
                    .timeout(Duration.ofSeconds(30))
                    .doOnNext(data -> {
                        try {
                            log.debug("收到AI服务原始数据: {}", data);

                            // 处理SSE格式数据
                            String cleanData = cleanSseData(data);

                            if ("[DONE]".equals(cleanData) || "data: [DONE]".equals(data.trim())) {
                                log.info("AI服务流式响应完成");
                                emitter.complete();
                                return;
                            }

                            if (!cleanData.isEmpty()) {
                                // 转发数据到前端
                                emitter.send(SseEmitter.event()
                                        .name("message")
                                        .data(cleanData));
                            }

                        } catch (Exception e) {
                            log.error("处理数据流失败: {}", e.getMessage());
                        }
                    })
                    .doOnError(error -> {
                        log.error("字符串流处理异常: {}", error.getMessage());
                        try {
                            emitter.send(SseEmitter.event()
                                    .name("error")
                                    .data("AI服务异常: " + error.getMessage()));
                            emitter.completeWithError(error);
                        } catch (Exception e) {
                            log.error("发送错误事件失败: {}", e.getMessage());
                        }
                    })
                    .doOnComplete(() -> {
                        log.info("字符串流正常完成 - 用户: {}", userId);
                        try {
                            emitter.complete();
                        } catch (Exception e) {
                            log.error("完成SSE发射器失败: {}", e.getMessage());
                        }
                    })
                    .subscribe();

        } catch (Exception e) {
            log.error("调用Python流式服务失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 清理SSE数据格式
     */
    private String cleanSseData(String rawData) {
        if (rawData == null || rawData.trim().isEmpty()) {
            return "";
        }

        String data = rawData.trim();

        // 处理SSE格式: "data: actual_content"
        if (data.startsWith("data: ")) {
            data = data.substring(6).trim();
        }

        // 移除可能的无效字符
        data = data.replaceAll("[\\x00-\\x1F\\x7F-\\x9F]", "");

        return data;
    }

    /**
     * 备用方案：使用ServerSentEvent但增加错误处理
     */
    private void callPythonStreamingServiceWithSseRetry(String userId, ChatRequest request, SseEmitter emitter) {
        try {
            WebClient webClient = createWebClientWithEncodingSupport();
            log.info("开始调用Python流式服务 (SSE模式): {}/chat/stream", aiServiceUrl);

            Flux<ServerSentEvent> eventStream = webClient.get()
                    .uri(uriBuilder -> uriBuilder
                            .path("/chat/stream")
                            .queryParam("sessionId", request.getSessionId())
                            .queryParam("userCurrentMessage", request.getUserMessage())
                            .build())
                    .retrieve()
                    .bodyToFlux(ServerSentEvent.class)
                    .onErrorResume(throwable -> {
                        log.warn("SSE解析错误，尝试降级处理: {}", throwable.getMessage());
                        // 如果SSE解析失败，返回空流并触发fallback
                        return Flux.empty();
                    });

            eventStream
                    .timeout(Duration.ofSeconds(30))
                    .doOnNext(event -> {
                        try {
                            String eventData = (String) event.data();
                            log.debug("收到AI服务SSE数据: {}", eventData);

                            if ("[DONE]".equals(eventData)) {
                                log.info("AI服务流式响应完成");
                                emitter.complete();
                                return;
                            }

                            emitter.send(SseEmitter.event()
                                    .name("message")
                                    .data(eventData));

                        } catch (Exception e) {
                            log.error("处理SSE事件失败: {}", e.getMessage());
                        }
                    })
                    .doOnError(error -> {
                        log.error("SSE流处理异常: {}", error.getMessage());
                        // 触发fallback模式
                        createFallbackStreamResponse(userId, request, emitter);
                        emitter.complete();
                    })
                    .doOnComplete(() -> {
                        log.info("SSE流正常完成 - 用户: {}", userId);
                        try {
                            emitter.complete();
                        } catch (Exception e) {
                            log.error("完成SSE发射器失败: {}", e.getMessage());
                        }
                    })
                    .subscribe();

        } catch (Exception e) {
            log.error("调用Python流式服务失败: {}", e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 健康检查
     */
    public boolean isAiServiceHealthy() {
        try {
            WebClient webClient = createWebClientWithEncodingSupport();

            String healthResponse = webClient.get()
                    .uri("/health")
                    .retrieve()
                    .bodyToMono(String.class)
                    .timeout(Duration.ofSeconds(5))
                    .block();

            log.debug("AI服务健康检查响应: {}", healthResponse);
            return healthResponse != null && healthResponse.contains("healthy");

        } catch (Exception e) {
            log.warn("AI服务健康检查失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * Fallback 响应
     */
    private void createFallbackStreamResponse(String userId, ChatRequest request, SseEmitter emitter) {
        try {
            log.info("使用fallback模式为用户 {} 提供响应", userId);

            String fallbackMessage = "抱歉，我现在有点累了，稍后再试试吧~ 🌸";
            char[] chars = fallbackMessage.toCharArray();

            for (char c : chars) {
                Thread.sleep(50);
                emitter.send(SseEmitter.event()
                        .name("message")
                        .data(String.valueOf(c)));
            }

        } catch (Exception e) {
            log.error("Fallback响应生成失败: {}", e.getMessage());
            throw new RuntimeException("Fallback响应失败", e);
        }
    }
}